#ifndef DEVICE_HPP
#define DEVICE_HPP

/********************************************************************
	created:	2011/01/15
	filename: 	E:\C++\Red\src\Graphics\Device.hpp
	author:		Red
	
	purpose:	Device. General object containing the window/render elements
				Use this to launch application
*********************************************************************/

#include "Input.hpp"
#include "Window.hpp"
#include "Gui/Gui.hpp"
#include "Lua/RedLua.hpp"

namespace red {

	/// Device Class, centralize all windowing/rendering/inputs for ease of use
	class REDAPI Device{
	public:
		Device();

		/// Initialization function. Create window and inputs for use
		void Initialize(u32 pWindowWidth, u32 pWindowHeight, const std::string &pWindowTitle);

		/// Initialize all Lua Class Binding
		void InitializeLuaClass();

		/// Destroy the Device
		void Shutdown();
				
		/// Begin rendering state
		void BeginRender();

		/// End rendering state
		void EndRender();

		void test() { std::cout << "LUA TEST" << std::endl; }

		// Getters
			/// Returns the device's Window
			Window& GetWindow() { return mWindow; }

			/// Returns the device's Inputs
			Input& GetInput() { return mInput; }

			/// Returns the device's Gui
			ui::Gui& GetGui() { return mGui; }

			/// Returns the device's Lua Interpreter
			Lua& GetLua() { return mLua; }

			/// Returns the device's state
			bool IsActive() { return mState; }

			/// Returns the static device instance
			static Device* GetDevice() { return mMainDevice; }

		// Setters
			/// Sets the background color
			void SetBackgroundColor(const Color &pColor) { mBackgroundColor = pColor; }

	private:
		Window	mWindow;			///< Device main window
		Input	mInput;				///< Device inputs
		ui::Gui	mGui;				///< Device Gui
		Lua		mLua;				///< Device Lua interpreter

		bool	mState;				///< Device's state. True = active
		Color	mBackgroundColor;	///< Application background color

		static Device* mMainDevice;	///< Static instance of this device, set when the device is created
	};




	/// Lua usable class for Device
	class LuaDevice {
	public:
		LuaDevice(lua_State* L) : mLuaGui(0) { }

		~LuaDevice() { 
			if(mLuaGui){
				delete mLuaGui;
				mLuaGui = 0;
			}
		}

		/// Return the LuaGui object instance present in this class
		int GetGui(lua_State* pState){
			// Create the LuaGui instance if it isn't yet created
			if(!mLuaGui)
				mLuaGui = new ui::LuaGui(&Device::GetDevice()->GetGui());

			// Send it to the Lua script
			Lunar<ui::LuaGui>::push(pState, mLuaGui);
			return 1;
		}

		/// Return the LuaInput object instance present in this class
		int GetInputs(lua_State* pState){
			return 0;
		}

		/// Return the LuaWindow object instance present in this class
		int GetWindow(lua_State* pState){
			return 0;
		}

		static const char className[];				///< Class Name, when called from script
		static Lunar<LuaDevice>::RegType methods[];	///< Methods Array

	private:
		ui::LuaGui* mLuaGui;	///< Only instance of LuaGui (do not call LuaGui directly from script. Get it from the Device)
	};
}

#endif // DEVICE_HPP
